package uam2

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/chromedp/cdproto/network"
	"github.com/chromedp/cdproto/target"
	"github.com/chromedp/chromedp"
	"github.com/sirupsen/logrus"
	"net/http"
	"net/http/httptest"
	"strings"
)

const (
	// 页面
	adminPage = "/admin/"

	// 接口
	userLogin = "/c/api/public/login"
)

func (s *UamStruct) MyFuncListenTarget() chromedp.Action {
	return chromedp.ActionFunc(func(ctx context.Context) error {
		chromedp.ListenTarget(ctx, func(ev interface{}) {
			switch e := ev.(type) {
			case *network.EventResponseReceived:
				go func() {
					switch e.Type {
					case network.ResourceTypeDocument:
						logrus.Debug("打开页面：", e.Response.URL)
					case network.ResourceTypeXHR:
						s.ajaxCheck(e)
					case network.ResourceTypeWebSocket:
						logrus.Debug("websocket：", e.Response.URL)
					case network.ResourceTypeFetch:
						logrus.Debug("请求 fetch 接口：", e.Response.URL)
					default:
						//	logrus.Debug("暂时用不到的其他类型请求：", e.RequestID.String())
					}
				}()
			}
		})
		return nil
	})
}

func (s *UamStruct) ajaxCheck(e *network.EventResponseReceived) {
	logrus.Debug("请求接口：", e.Response.URL[len(s.url):])
	url := e.Response.URL[len(s.url):]
	if !strings.HasPrefix(url, "/") {
		url = "/" + url
	}
	if strings.Contains(url, "url") {
		url = url[:strings.Index(url, "?")]
	}
	switch e.Response.URL[len(s.url):] {
	case userLogin:
		s.loginAjax(e)
	default:
		//logrus.Debug("还未处理的接口")
	}
}

func (s *UamStruct) loginAjax(e *network.EventResponseReceived) {
	// 监听登录行为
	b, err := network.GetResponseBody(e.RequestID).Do(s.ctx)
	var result map[string]interface{}
	err = json.Unmarshal(b, &result)
	if err != nil {
		logrus.Error(err, "接口 c/api/public/login 返回值不是一个json")
	}
	// Golang 使用 JSON unmarshal() 序列化 int 被转成 float64 类型，因此需要强转回来
	//if result["code"].(int) == 101 {
	//	logrus.Debug("需要二次确认登录")
	//}
	if result["token"] == "" {
		logrus.Debug("点击二次确认登录按钮")
		s.remoteLoginC <- 1
	} else {
		logrus.Debug("获取到token", result["token"])
		s.token = fmt.Sprintf("%v", result["token"])
		s.remoteLoginC <- 1
	}
}

func (s UamStruct) docCheck(e *network.EventResponseReceived) {
	logrus.Debug("新页面： ", e.Response.URL[len(s.url):])
	url := e.Response.URL[len(s.url):]
	if !strings.HasPrefix(url, "/") {
		url = "/" + url
	}
	switch e.Response.URL[len(s.url):] {
	case adminPage:
		logrus.Debug("进入管理页面")
	default:
		logrus.Debug("还未处理的页面")
	}
}

func (s *UamStruct) MyFuncRegisterNewTarget() chromedp.ActionFunc {
	return func(ctx context.Context) error {
		go func() {
			mux := http.NewServeMux()
			ts := httptest.NewServer(mux)
			defer ts.Close()
			// 等待新页面打开
			ch := chromedp.WaitNewTarget(ctx, func(info *target.Info) bool {
				logrus.Debugf("打开新页面,url: %s,TargetID:%s", info.URL, info.TargetID)
				return info.URL != ""
			})
			// 将新开页面设置到上下文中
			s.newCtx, s.cancel = chromedp.NewContext(ctx, chromedp.WithTargetID(<-ch))
			chromedp.Run(s.newCtx,
				chromedp.WaitVisible(`#app`, chromedp.ByID),
				chromedp.ActionFunc(func(ctx context.Context) error {
					chromedp.ListenTarget(ctx, func(ev interface{}) {
						switch e := ev.(type) {
						case *network.EventResponseReceived:
							go func() {
								switch e.Type {
								case network.ResourceTypeDocument:
									logrus.Debug("222 document：", e.Response.URL)
									//s.docCheck(e)
								case network.ResourceTypeXHR:
									logrus.Debug("222 ajax：", e.Response.URL)
								case network.ResourceTypeWebSocket:
									logrus.Debug("websocket：", e.Response.URL)
								case network.ResourceTypeFetch:
									logrus.Debug("请求 fetch 接口：", e.Response.URL)
								default:
									//	logrus.Debug("暂时用不到的其他类型请求：", e.RequestID.String())
								}
							}()
						}
					})
					return nil
				}),
				s.adminLogin(),
				s.addCluster(),
			)
		}()
		return nil
	}
}

func (s *UamStruct) MyFuncListenQuit() chromedp.ActionFunc {
	return func(ctx context.Context) error {
		for {
			select {
			case <-s.ctx.Done():
				logrus.Info("浏览器被关闭，退出进程")
				return errors.New("浏览器被关闭，退出进程")
			default:
			}
		}
	}
}
